
#encoding:utf-8

'''
Created on 6 avr. 2011

@author: paraita

    mon wrapper wiimote-python
    j'utilise la librairie lightblue qui permet
    de jumeler des périphériques et ouvrir des
    sockets pour communiquer
    
    j'ai utilisé le site http://wiibrew.org/wiki/Wiimote
    pour savoir quoi envoyer et comment traiter les donnees recues
    
    j'ai pioché sur internet le module hexbyte qui me permet
    la conversion octet->hexa et dans l'autre sens aussi
    
'''

import lightblue
import sys
import hexbyte
import time

class MyWiimote(object):
    
    nom = 'Nintendo RVL-CNT-01'
    mac = 0
    socket_write = 0
    socket_read = 0
    wiimote = 0
    connected = False
    
    def __init__(self):
        object.__init__(self)
        pass
        
    def recherche(self, addr=0):
        self.mac = addr
        self.wiimote = addr
        '''
            recherche d'une wiimote. Pour aller plus vite, et si la wiimote
            est deja en mode connectée, on peut donner l'adresse mac
            de la wiimote directement
        '''
        print "recherche des périphériques bluetooth aux environs"
        devs = lightblue.finddevices(getnames=True, length=5)
        print "liste des devices chopé aux alentours:"
        for d in devs:
            print d
        # je prend le bon suivant son nom ou 
        if addr == 0:
            for d in devs:
                if d[1] == self.nom:
                    self.wiimote = d[0]
                    break
        else:
            for d in devs:
                if d[0] == self.mac:
                    self.wiimote = d[0]
                    break
        if not self.wiimote:
            print "pas de wiimote trouvé !"
            sys.exit(1)
        else:
            print "wiimote:",self.wiimote
    
    def configure(self):
        '''
            ouverture des sockets de lecture et d'ecriture
        '''
        print "wiimote mac adresse:", self.wiimote
        
        # socket d'envoie de commandes
        self.socket_write = lightblue.socket(lightblue.L2CAP)
        self.socket_write.connect((self.wiimote, 0x11)) 
         
        # met la wii en mode 'je t'écoute'
        self.socket_write.send(hexbyte.HexToByte('52 12 00 31'))
        
        # socket lecture des donnees de la wiimote
        self.socket_read = lightblue.socket(lightblue.L2CAP)
        self.socket_read.connect((self.wiimote, 0x13)) 
        
        #jusque la y'a pas eu de probleme
        self.connected = True
    
    def send(self,data):
        '''
            envoyer des donnees bien formées a la wiimote
            on considere que l'utilisateur a bien formé sa donnée
        '''
        if not self.connected:
            print "wiimote non connectée"
            return
        else:
            self.socket_write.send(hexbyte.HexToByte(data))
    
    def vibre(self,nb):
        '''
            permet de faire vibrer la wiimote pendant nb secondes
        '''
        if not self.connected:
            print "wiimote non connectée"
            return
        else:
            # test de secousse pour montrer qu'on a reussi a se connecter
            self.socket_write.send(hexbyte.HexToByte('52 11 01'))
            time.sleep(nb)
            self.socket_write.send(hexbyte.HexToByte('52 11 00'))
    
    def isBouttonAPressed(self):
        '''
            predicat: est ce que le bouton A est pressé ?
        '''
        donnees = self.getRawData().split(' ')
        if donnees[3][1] == '8':
            return True
        else:
            return False
        
    def getRawData(self):
        '''
            retourne les donnees bouttons+accel au format hexa (x31)
            sur 7 octets
        '''
        if not self.connected:
            print "wiimote non connectée"
            return ""
        else:
            self.socket_write.send(hexbyte.HexToByte('52 12 00 31'))
            octet = self.socket_read.recv(256*7)
            donneesBrute = hexbyte.ByteToHex(octet)
            aTester = donneesBrute.split(' ')
            while len(aTester) != 7:
                self.socket_write.send(hexbyte.HexToByte('52 12 00 31'))
                octet = self.socket_read.recv(256*7)
                donneesBruteBis = hexbyte.ByteToHex(octet)
                aTester = donneesBruteBis.split(' ')
                donneesBrute = donneesBruteBis
            return donneesBrute
        
    def getAcc(self):
        '''
            retourne les valeurs d'acceleration non calibrée
            (retourne par defaut x80)
        '''
        donneesNonCalibrees = self.getRawData()
        donneesNonCalibrees = donneesNonCalibrees.split(' ')
        ax = int(donneesNonCalibrees[4], 16)
        ay = int(donneesNonCalibrees[5], 16)
        az = int(donneesNonCalibrees[6], 16)
        return ax,ay,az
    
    def getAccCalibred(self):
        '''
            retourne les valeurs d'acceleration calibrée
        '''
        x,y,z = self.getAcc()
        x -= 127
        y -= 127
        z -= 127
        return x,y,z
